<?php

namespace app\admin\model\scanwork;

use think\Model;

/**
 * 生产计划模型
 */
class ProductionPlan extends Model
{
    // 表名
    protected $name = 'scanwork_production_plan';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    
    // 追加属性
    protected $append = [
        'status_text'
    ];
    
    // 生产计划状态
    public function getStatusList()
    {
        return [
            '0' => __('未开始'),
            '1' => __('进行中'),
            '2' => __('已暂停'),
            '3' => __('已完成')
        ];
    }

    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    // 关联订单
    public function order()
    {
        return $this->belongsTo('app\admin\model\scanwork\Order', 'order_id', 'id');
    }

    // 关联产品
    public function product()
    {
        return $this->belongsTo('app\admin\model\scanwork\Product', 'product_id', 'id');
    }

    // 关联型号
    public function model()
    {
        return $this->belongsTo('app\admin\model\scanwork\ProductModel', 'model_id', 'id');
    }

    // 关联客户
    public function customer()
    {
        return $this->belongsTo('app\admin\model\scanwork\Customer', 'customer_id', 'id');
    }

    // 关联分工分配
    public function allocations()
    {
        return $this->hasMany('app\admin\model\scanwork\Allocation', 'order_id', 'order_id');
    }

    // 获取计划编码
    public function getPlanCodeAttr($value, $data)
    {
        if (empty($value) && isset($data['id'])) {
            $value = 'JH-' . date('Y') . '-' . str_pad($data['id'], 3, '0', STR_PAD_LEFT);
        }
        return $value;
    }

    // 检查计划编码是否唯一
    public function checkCodeUnique($code, $id = null)
    {
        $where = ['plan_code' => $code];
        if ($id) {
            $where['id'] = ['<>', $id];
        }
        return $this->where($where)->count() == 0;
    }


    // 获取生产进度
    public function getProgressAttr($value, $data)
    {
        if (isset($data['id'])) {
            $allocations = $this->allocations();
            $totalAllocated = $allocations->sum('quantity');
            $totalReported = $allocations->sum('reported_quantity');
            
            if ($totalAllocated == 0) {
                return 0;
            }
            
            return round(($totalReported / $totalAllocated) * 100, 2);
        }
        return $value ?: 0;
    }

    // 自动更新生产进度
    public function updateProgress()
    {
        $allocations = $this->allocations();
        $totalAllocated = $allocations->sum('quantity');
        $totalReported = $allocations->sum('reported_quantity');
        
        $progress = 0;
        if ($totalAllocated > 0) {
            $progress = round(($totalReported / $totalAllocated) * 100, 2);
        }
        
        $this->save(['progress' => $progress]);
        
        // 根据进度自动更新状态
        if ($progress >= 100) {
            $this->save(['status' => 2, 'actual_end_time' => time()]); // 已完成
        } elseif ($progress > 0 && $this->status == 0) {
            $this->save(['status' => 1, 'actual_start_time' => time()]); // 进行中
        }
    }

    // 自动更新计划状态
    public function updateStatus()
    {
        $allocations = $this->allocations();
        $totalAllocated = $allocations->sum('quantity');
        $totalReported = $allocations->sum('reported_quantity');
        
        if ($totalAllocated == 0) {
            $this->save(['status' => 0]); // 待开始
        } elseif ($totalReported >= $totalAllocated) {
            $this->save(['status' => 2, 'actual_end_time' => time()]); // 已完成
        } elseif ($totalReported > 0) {
            $this->save(['status' => 1]); // 进行中
            if (!$this->actual_start_time) {
                $this->save(['actual_start_time' => time()]);
            }
        }
    }

    // 生成默认工序顺序
    public function generateDefaultProcessSequence()
    {
        if (!$this->product_id) {
            return [];
        }
        
        $product = \app\admin\model\scanwork\Product::get($this->product_id);
        if (!$product || empty($product->process_route)) {
            return [];
        }
        
        $processRoute = json_decode($product->process_route, true);
        if (!$processRoute || !is_array($processRoute)) {
            return [];
        }
        
        $sequence = [];
        foreach ($processRoute as $processName) {
            $process = \app\admin\model\scanwork\Process::where('name', $processName)
                ->where('status', 1)
                ->find();
            if ($process) {
                $sequence[] = [
                    'process_id' => $process->id,
                    'process_name' => $process->name,
                    'sequence' => count($sequence) + 1,
                    'estimated_hours' => $process->standard_time
                ];
            }
        }
        
        return $sequence;
    }

    // 生成关键生产节点
    public function generateKeyMilestones()
    {
        $processSequence = $this->process_sequence;
        if (empty($processSequence)) {
            return [];
        }
        
        $milestones = [];
        $totalProcesses = count($processSequence);
        
        foreach ($processSequence as $index => $process) {
            $milestone = [
                'name' => $process['process_name'] . '完成',
                'process_id' => $process['process_id'],
                'sequence' => $index + 1,
                'estimated_time' => $this->planned_start_time + ($index + 1) * 86400, // 假设每个工序1天
                'status' => 'pending'
            ];
            $milestones[] = $milestone;
        }
        
        return $milestones;
    }

    // 获取计划统计信息
    public function getPlanStats()
    {
        // 根据plan_id查询对应的分工分配
        $allocations = \app\admin\model\scanwork\Allocation::where('plan_id', $this->id)
            ->select();
            
        $totalAllocated = 0;
        $totalReported = 0;
        $totalHours = 0;
        $allocationCount = count($allocations);
        
        foreach ($allocations as $allocation) {
            $totalAllocated += $allocation->quantity;
            $totalHours += $allocation->actual_hours;
            
            // 直接从报工表计算已完成数量
            $reportedQuantity = \app\admin\model\scanwork\Report::where('allocation_id', $allocation->id)
                ->where('status', 1)
                ->sum('quantity');
            $totalReported += $reportedQuantity ?: 0;
        }
        
        return [
            'total_allocated' => $totalAllocated,
            'total_reported' => $totalReported,
            'remaining_quantity' => max(0, $totalAllocated - $totalReported),
            'completion_rate' => $totalAllocated > 0 ? round($totalReported / $totalAllocated * 100, 2) : 0,
            'total_hours' => $totalHours,
            'allocation_count' => $allocationCount,
            'estimated_days' => $this->planned_end_time && $this->planned_start_time ? 
                ceil(($this->planned_end_time - $this->planned_start_time) / 86400) : 0
        ];
    }

    // 检查计划是否可以开始
    public function canStart()
    {
        // 未开始(0)状态可以开始
        return $this->status == 0;
    }

    // 检查计划是否可以暂停
    public function canPause()
    {
        // 进行中(1)状态可以暂停
        return $this->status == 1;
    }

    // 检查计划是否可以恢复
    public function canResume()
    {
        // 已暂停(2)状态可以恢复
        return $this->status == 2;
    }

    // 开始计划
    public function start()
    {
        if (!$this->canStart()) {
            throw new \Exception('计划当前状态不允许开始');
        }
        
        $this->save([
            'status' => 1, // 设置为进行中状态
            'actual_start_time' => time()
        ]);
    }

    // 暂停计划
    public function pause()
    {
        if (!$this->canPause()) {
            throw new \Exception('计划当前状态不允许暂停');
        }
        
        $this->save(['status' => 2]); // 设置为已暂停状态
    }

    // 恢复计划
    public function resume()
    {
        if (!$this->canResume()) {
            throw new \Exception('计划当前状态不允许恢复');
        }
        
        $this->save(['status' => 1]); // 恢复为进行中状态
    }

    // 完成计划
    public function complete()
    {
        if ($this->status == 3) {
            throw new \Exception('计划已经完成');
        }
        
        $this->save([
            'status' => 3, // 设置为已完成状态
            'actual_end_time' => time(),
            'progress' => 100
        ]);
    }
}
